iT邦幫忙

DAY 23
0

從想法到快速實作的捷徑:Rails系列 第 23

[ Day 23 ][ Dev ] 實作角色權限管理 - Part 1

  • 分享至 

  • xImage
  •  

還記得很久很久以前,

我們曾經在view做過對po文編輯或刪除的限制,

不過這樣只是眼不見為淨而已,還是可以靠輸入網址去進入想看的頁面。

所以我們在controller加上這一行:

before_action :authenticate_user!

現在只有一個post要處理,

假如是大一點的project該怎樣做?

如果一樣在每個view和controller都要加上限制,

那真的是煩死人的事情,萬一有哪裡忘記加上權限管理,

你沒有辦法一目了然地找到。

所以,有沒有什麼辦法把所有的權限管理給集中起來,再也不分view和controller呢?

CanCanCan可以!

我不是結巴,是有個gem叫做cancancan。(之前叫做cancan,不過已經太久沒有維護了)

一樣先把cancancan加入Gemfile、安裝,

這裡就不再贅述要怎麼做了。

接著執行: rails g cancan:ability

會產生一隻aibility.rb的檔案,

class Ability
    include CanCan::Ability

    def initialize(user)

        # Define abilities for the passed in user here. For example:
        #
        #   user ||= User.new # guest user (not logged in)
        #   if user.admin?
        #     can :manage, :all
        #   else
        #     can :read, :all
        #   end
        #
        # The first argument to `can` is the action you are giving the user
        # permission to do.
        # If you pass :manage it will apply to every action. Other common actions
        # here are :read, :create, :update and :destroy.
        #
        # The second argument is the resource the user can perform the action on.
        # If you pass :all it will apply to every resource. Otherwise pass a Ruby
        # class of the resource.
        #
        # The third argument is an optional hash of conditions to further filter the
        # objects.
        # For example, here the user can only update published articles.
        #
        #   can :update, Article, :published => true
        #
        # See the wiki for details:
        # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities

    end

end

其實打到這裡已經可以結束了,

因為看Readme和註解其實就講的很清楚XD

簡單的權限管理是很直觀能處理的,

像是這樣:

        if user.blank? #驗證user是不是有登入,如果沒有的話執行下方這一段
            cannot :manage, :all                             #先將執行所有權限的能力取消
            basic_read_only                                        #只能基本的看Post(包括show index......等)
        else #下方就是有登入的user能做的事情
            can :create, Post                                 # 包括new跟create
            can :update, Post do |post|              
                (post.user_id == user.id)            # 讓user只能編輯自己的post(下方不贅述啦)
            end
            can :destroy, Post do |post|
                (post.user_id == user.id)
            end
            basic_read_only
        end

如果有太多重複的方法也可以抽出來放在下方,就跟之前在controller抽出來。

protected

    def basic_read_only
        can :read,    Post
    end

最後要把驗證放進去controller該怎麼做呢?

就是在posts_controller.rb裡面加上

authorize_resource :post

因為cancan認的是resource的名字,所以記得要將變數命名成@post。

最後就可以把剛剛在view裡面post.user\_id == current\_user.id給拿掉,

換成

can? :update, post

如果只做到這樣的話,那還是沒有做完最核心的審核發文功能。

所以下來我們要捲起袖子來改一些東西啦!

要想把admin給做出來,其實有很多種方式,

有興趣知道其他方法的可以去參考devise的wiki裡面怎麼寫。

(講到使用者其實也就是那幾個gem用來用去XD)

實作admin角色

而admin和前台的layout當然要做一些區別,

在rails裡面做法很簡單,

假如說我們有個layout版型叫做admin.html.erb放在app/views/layouts/底下,

我們只要在controller底下呼叫layout 'admin'就能夠使用了,

所以在這裡我們將在admin/posts_controller底下加入這一行。

But,這樣當專案變大,每次新增就會都要重加一次,有沒有什麼好的解法呢?

利用簡單的繼承來分開前台後台

沒有錯,又是繼承,在ruby裡面繼承的符號長這樣:son **<** parent

這代表son繼承自parent的意思。

所以這裡我們打開admin/posts_controller來看,

發現他跟其他controller一樣都繼承自application controller,

為了將前台後台分開,我們將新增一個一樣繼承自application controller的admin controller,

可以把它當成是「後台的application controller」,

所有跟後台相關的controller都可以繼承自admin controller,

在這裡加上layout和是否為admin的限制就可將前台後台分開了(model和view部分我們已經處理完啦)

好的,現在我們的客製化後台已經有了個雛形,

下一篇將繼續完成後台的管理功能。

參考資料:

  1. CanCanCan:
    http://blog.xdite.net/posts/2012/07/30/cancan-rule-engine-authorization-based-library-2/
    https://github.com/CanCanCommunity/cancancan

  2. 實作admin角色
    https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-Role


上一篇
[ Day 22 ] DIY實作後台功能
下一篇
[ Day 24 ][ Dev ] 實作角色權限管理 - Part 2
系列文
從想法到快速實作的捷徑:Rails30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言